return {
	{
		'nvim-treesitter/nvim-treesitter',
		build = ':TSUpdate',
		config = function()
			require('nvim-treesitter.configs').setup {
				ensure_installed = -- "maintained",
				{
					"bash",
					"lua",
					"rust",
					"toml",
					"python",
					"javascript",
					"typescript",
					"json",
					"html",
					"http",
					"dockerfile",
					"yaml",
					"vue",
					"query",
					"wgsl",
					"markdown",
					"markdown_inline",
					-- needs treesitter cli for this
					-- install with `npm install -g tree-sitter-cli`
					"latex",
					"dockerfile"
				},
				-- one of "all", "maintained" (parsers with maintainers), or a list of languages
				highlight = {
					enable = true, -- false will disable the whole extension
					-- Setting this to true will run `:h syntax` and tree-sitter at the same time.
					-- Set this to `true` if you depend on 'syntax' being enabled (like for indentation).
					-- Using this option may slow down your editor, and you may see some duplicate highlights.
					-- Instead of true it can also be a list of languages
					additional_vim_regex_highlighting = false,
				},
				incremental_selection = {
					enable = true,
					keymaps = {
						init_selection = "vv",
						node_incremental = "+",
						-- scope_incremental = "g+",
						node_decremental = "-",
					},
				},
				indent = {
					enable = false -- Tested with lua 'function () <Enter> end <Enter>', 'end' is not correctly indented
				},
				textobjects = {
					select = {
						enable = true,
						lookahead = true,
						keymaps = {
							["af"] = "@function.outer",
							["if"] = "@function.inner",
							["as"] = "@block.outer",
							["is"] = "@block.inner",
						}
					},
					move = {
						enable = true,
						set_jumps = true,
						goto_next_start = {
							["]F"] = "@function.outer",
							["]f"] = "@function.inner",
							["]S"] = "@block.outer",
							["]s"] = "@block.inner",
						},
						goto_previous_start = {
							["[F"] = "@function.outer",
							["[f"] = "@function.inner",
							["[S"] = "@block.outer",
							["[s"] = "@block.inner",
						},
					}
				}
			};

			vim.o.foldlevel = 20
			vim.o.foldmethod = 'expr'
			vim.o.foldexpr = 'nvim_treesitter#foldexpr()'
		end
	},
	{
		'nvim-treesitter/nvim-treesitter-textobjects',
		dependencies = { 'nvim-treesitter/nvim-treesitter' }
	},
	{
		"drybalka/tree-climber.nvim",
		config = function()
			local climber = require('tree-climber')

			local keyopts = { noremap = true, silent = true }
			vim.keymap.set({ 'n', 'v', 'o' }, '<a-h>', climber.goto_parent, keyopts)
			vim.keymap.set({ 'n', 'v', 'o' }, '<a-l>', climber.goto_child, keyopts)
			vim.keymap.set({ 'n', 'v', 'o' }, '<a-j>', climber.goto_next, keyopts)
			vim.keymap.set({ 'n', 'v', 'o' }, '<a-k>', climber.goto_prev, keyopts)
		end
	}
};
